from bases.ui_modules import gtk
from Bases import BaseObject
from bases import widgets, tree

class OSCTree(BaseObject):
    def __init__(self, **kwargs):
        super(OSCTree, self).__init__(**kwargs)
        self.root_node = kwargs.get('root_node')
        self.store = gtk.TreeStore(str)
        self.root_item = OSCTreeItem(store=self.store, osc_node=self.root_node)
        self.topwidget = widgets.VBox()
        self.widget = gtk.TreeView()
        self.widget.get_selection().connect('changed', self.on_widget_sel_changed)
        self.scrolled_win = widgets.ScrolledWindow()
        self.scrolled_win.add(self.widget)
        self.topwidget.pack_start(self.scrolled_win, expand=True)
        self.widget.set_model(self.store)
        for i, key in enumerate(['name']):
            cell = gtk.CellRendererText()
            col = gtk.TreeViewColumn(key, cell, text=i)
            self.widget.append_column(col)
        btn = widgets.Button(label='Refresh')
        btn.connect('clicked', self.refresh)
        self.topwidget.pack_start(btn, expand=False)
        self.root_item.bind(child_added=self.on_root_child_added, 
                            child_removed=self.on_root_child_removed)
            
    def on_widget_sel_changed(self, *args):
        pass
        
    def refresh(self, *args):
        self.root_item.unlink_all(remove=True)
        self.root_item = OSCTreeItem(store=self.store, osc_node=self.root_node)
        
    def on_root_child_added(self, **kwargs):
        print 'child_added: ', kwargs
    def on_root_child_removed(self, **kwargs):
        print 'child_removed: ', kwargs
            
class OSCTreeItem(BaseObject):
    def __init__(self, **kwargs):
        super(OSCTreeItem, self).__init__(**kwargs)
        self._store = kwargs.get('store')
        self.tree_parent = kwargs.get('tree_parent')
        self.osc_node = kwargs.get('osc_node')
        self.tree_children = {}
        self.iter = self.store.append(self.parent_iter, self.build_row())
        self.add_child()
        self.osc_node.bind(child_added=self.on_osc_node_child_added, 
                           child_removed=self.on_osc_node_child_removed)
        
    def unlink(self):
        self.osc_node.unbind(self)
        super(OSCTreeItem, self).unlink()
        
    def unlink_all(self, remove=False):
        self.unlink()
        for key in self.tree_children.keys()[:]:
            child = self.tree_children[key]
            child.unlink_all(remove)
            if remove:
                #self.store.remove(child.iter)
                del self.tree_children[key]
        if remove:
            self.store.remove(self.iter)
        
    @property
    def store(self):
        if self._store is not None:
            return self._store
        return self.tree_parent.store
        
    @property
    def parent_iter(self):
        if self.tree_parent:
            return self.tree_parent.iter
        return None
        
    def build_row(self):
        if self.osc_node.is_root_node:
            address = '/'
            name = '/'
        else:
            address = '/'.join(self.osc_node.get_full_path())
            name = self.osc_node._name
        return [name]
        
    def add_child(self, name=None):
        if name is None:
            names = self.osc_node._childNodes.keys()
        else:
            names = [name]
        for name in names:
            node = self.osc_node._childNodes.get(name)
            if node is None:
                continue
            tree_item = OSCTreeItem(tree_parent=self, osc_node=node)
            self.tree_children[name] = tree_item
            
    def remove_child(self, name):
        child = self.tree_children.get(name)
        if not child:
            return
        child.unlink()
        if self.store.iter_is_valid(child.iter):
            self.store.remove(child.iter)
        del self.tree_children[name]
        
    
    def on_osc_node_child_added(self, **kwargs):
        name = kwargs.get('name')
        node = kwargs.get('node')
        if node == self.osc_node:
            self.add_child(name)
    
    def on_osc_node_child_removed(self, **kwargs):
        name = kwargs.get('name')
        node = kwargs.get('node')
        if node == self.osc_node:
            self.remove_child(name)
